"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.assembleColumn = assembleColumn;
exports.calcTreeLine = calcTreeLine;
exports.clearTableAllStatus = clearTableAllStatus;
exports.clearTableDefaultStatus = clearTableDefaultStatus;
exports.colToVisible = colToVisible;
exports.convertHeaderColumnToRows = void 0;
exports.createColumn = createColumn;
exports.destroyColumn = destroyColumn;
exports.getCellHeight = getCellHeight;
exports.getCellValue = getCellValue;
exports.getColReMaxWidth = getColReMaxWidth;
exports.getColReMinWidth = getColReMinWidth;
exports.getOffsetSize = void 0;
exports.getRefElem = getRefElem;
exports.getRootColumn = getRootColumn;
exports.getRowUniqueId = getRowUniqueId;
exports.getRowid = getRowid;
exports.getRowkey = getRowkey;
exports.handleFieldOrColumn = void 0;
exports.isColumnInfo = isColumnInfo;
exports.mergeBodyMethod = mergeBodyMethod;
exports.restoreScrollLocation = restoreScrollLocation;
exports.rowToVisible = rowToVisible;
exports.setCellValue = setCellValue;
exports.toFilters = toFilters;
exports.toTreePathSeq = toTreePathSeq;
exports.watchColumn = watchColumn;
var _vue = require("vue");
var _xeUtils = _interopRequireDefault(require("xe-utils"));
var _columnInfo = require("./columnInfo");
var _dom = require("../../ui/src/dom");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const getAllConvertColumns = (columns, parentColumn) => {
  const result = [];
  columns.forEach(column => {
    column.parentId = parentColumn ? parentColumn.id : null;
    if (column.visible) {
      if (column.children && column.children.length && column.children.some(column => column.visible)) {
        result.push(column);
        result.push(...getAllConvertColumns(column.children, column));
      } else {
        result.push(column);
      }
    }
  });
  return result;
};
const convertHeaderColumnToRows = originColumns => {
  let maxLevel = 1;
  const traverse = (column, parent) => {
    if (parent) {
      column.level = parent.level + 1;
      if (maxLevel < column.level) {
        maxLevel = column.level;
      }
    }
    if (column.children && column.children.length && column.children.some(column => column.visible)) {
      let colSpan = 0;
      column.children.forEach(subColumn => {
        if (subColumn.visible) {
          traverse(subColumn, column);
          colSpan += subColumn.colSpan;
        }
      });
      column.colSpan = colSpan;
    } else {
      column.colSpan = 1;
    }
  };
  originColumns.forEach(column => {
    column.level = 1;
    traverse(column);
  });
  const rows = [];
  for (let i = 0; i < maxLevel; i++) {
    rows.push([]);
  }
  const allColumns = getAllConvertColumns(originColumns);
  allColumns.forEach(column => {
    if (column.children && column.children.length && column.children.some(column => column.visible)) {
      column.rowSpan = 1;
    } else {
      column.rowSpan = maxLevel - column.level + 1;
    }
    rows[column.level - 1].push(column);
  });
  return rows;
};
exports.convertHeaderColumnToRows = convertHeaderColumnToRows;
function restoreScrollLocation($xeTable, scrollLeft, scrollTop) {
  const internalData = $xeTable.internalData;
  return $xeTable.clearScroll().then(() => {
    if (scrollLeft || scrollTop) {
      // 重置最后滚动状态
      internalData.lastScrollLeft = 0;
      internalData.lastScrollTop = 0;
      internalData.intoRunScroll = false;
      internalData.inVirtualScroll = false;
      internalData.inWheelScroll = false;
      internalData.inHeaderScroll = false;
      internalData.inBodyScroll = false;
      internalData.inFooterScroll = false;
      internalData.scrollRenderType = '';
      // 还原滚动状态
      return $xeTable.scrollTo(scrollLeft, scrollTop);
    }
  });
}
/**
 * 生成行的唯一主键
 */
function getRowUniqueId() {
  return _xeUtils.default.uniqueId('row_');
}
// 行主键 key
function getRowkey($xeTable) {
  const {
    props
  } = $xeTable;
  const {
    computeRowOpts
  } = $xeTable.getComputeMaps();
  const {
    rowId
  } = props;
  const rowOpts = computeRowOpts.value;
  return rowId || rowOpts.keyField || '_X_ROW_KEY';
}
// 行主键 value
function getRowid($xeTable, row) {
  const rowid = _xeUtils.default.get(row, getRowkey($xeTable));
  return _xeUtils.default.eqNull(rowid) ? '' : encodeURIComponent(rowid);
}
const handleFieldOrColumn = ($xeTable, fieldOrColumn) => {
  if (fieldOrColumn) {
    return _xeUtils.default.isString(fieldOrColumn) || _xeUtils.default.isNumber(fieldOrColumn) ? $xeTable.getColumnByField(`${fieldOrColumn}`) : fieldOrColumn;
  }
  return null;
};
exports.handleFieldOrColumn = handleFieldOrColumn;
function getPaddingLeftRightSize(elem) {
  if (elem) {
    const computedStyle = getComputedStyle(elem);
    const paddingLeft = _xeUtils.default.toNumber(computedStyle.paddingLeft);
    const paddingRight = _xeUtils.default.toNumber(computedStyle.paddingRight);
    return paddingLeft + paddingRight;
  }
  return 0;
}
function getElementMarginWidth(elem) {
  if (elem) {
    const computedStyle = getComputedStyle(elem);
    const marginLeft = _xeUtils.default.toNumber(computedStyle.marginLeft);
    const marginRight = _xeUtils.default.toNumber(computedStyle.marginRight);
    return elem.offsetWidth + marginLeft + marginRight;
  }
  return 0;
}
function queryCellElement(cell, selector) {
  return cell.querySelector('.vxe-cell' + selector);
}
function toFilters(filters) {
  if (filters && _xeUtils.default.isArray(filters)) {
    return filters.map(({
      label,
      value,
      data,
      resetValue,
      checked
    }) => {
      return {
        label,
        value,
        data,
        resetValue,
        checked: !!checked,
        _checked: !!checked
      };
    });
  }
  return filters;
}
function toTreePathSeq(path) {
  return path.map((num, i) => i % 2 === 0 ? Number(num) + 1 : '.').join('');
}
function getCellValue(row, column) {
  return _xeUtils.default.get(row, column.field);
}
function setCellValue(row, column, value) {
  return _xeUtils.default.set(row, column.field, value);
}
function getRefElem(refEl) {
  if (refEl) {
    const rest = refEl.value;
    if (rest) {
      return rest.$el || rest;
    }
  }
  return null;
}
function getCellHeight(height) {
  if (height === 'unset') {
    return 0;
  }
  return height || 0;
}
/**
 * 列宽拖动最大宽度
 * @param params
 * @returns
 */
function getColReMaxWidth(params) {
  const {
    $table
  } = params;
  const {
    computeResizableOpts
  } = $table.getComputeMaps();
  const resizableOpts = computeResizableOpts.value;
  const {
    maxWidth: reMaxWidth
  } = resizableOpts;
  // 如果自定义调整宽度逻辑
  if (reMaxWidth) {
    const customMaxWidth = _xeUtils.default.isFunction(reMaxWidth) ? reMaxWidth(params) : reMaxWidth;
    if (customMaxWidth !== 'auto') {
      return Math.max(1, _xeUtils.default.toNumber(customMaxWidth));
    }
  }
  return -1;
}
/**
 * 列宽拖动最小宽度
 * @param params
 * @returns
 */
function getColReMinWidth(params) {
  const {
    $table,
    column,
    cell
  } = params;
  const tableProps = $table.props;
  const internalData = $table.internalData;
  const {
    computeResizableOpts
  } = $table.getComputeMaps();
  const resizableOpts = computeResizableOpts.value;
  const {
    minWidth: reMinWidth
  } = resizableOpts;
  // 如果自定义调整宽度逻辑
  if (reMinWidth) {
    const customMinWidth = _xeUtils.default.isFunction(reMinWidth) ? reMinWidth(params) : reMinWidth;
    if (customMinWidth !== 'auto') {
      return Math.max(1, _xeUtils.default.toNumber(customMinWidth));
    }
  }
  const {
    elemStore
  } = internalData;
  const {
    showHeaderOverflow: allColumnHeaderOverflow
  } = tableProps;
  const {
    showHeaderOverflow,
    minWidth: colMinWidth
  } = column;
  const headOverflow = _xeUtils.default.isUndefined(showHeaderOverflow) || _xeUtils.default.isNull(showHeaderOverflow) ? allColumnHeaderOverflow : showHeaderOverflow;
  const showEllipsis = headOverflow === 'ellipsis';
  const showTitle = headOverflow === 'title';
  const showTooltip = headOverflow === true || headOverflow === 'tooltip';
  const hasEllipsis = showTitle || showTooltip || showEllipsis;
  const minTitleWidth = _xeUtils.default.floor((_xeUtils.default.toNumber(getComputedStyle(cell).fontSize) || 14) * 1.6);
  const paddingLeftRight = getPaddingLeftRightSize(cell) + getPaddingLeftRightSize(queryCellElement(cell, ''));
  let mWidth = minTitleWidth + paddingLeftRight;
  // 默认最小宽处理
  if (hasEllipsis) {
    const dragIconWidth = getPaddingLeftRightSize(queryCellElement(cell, '>.vxe-cell--drag-handle'));
    const checkboxIconWidth = getPaddingLeftRightSize(queryCellElement(cell, '>.vxe-cell--checkbox'));
    const requiredIconWidth = getElementMarginWidth(queryCellElement(cell, '>.vxe-cell--required-icon'));
    const editIconWidth = getElementMarginWidth(queryCellElement(cell, '>.vxe-cell--edit-icon'));
    const prefixIconWidth = getElementMarginWidth(queryCellElement(cell, '>.vxe-cell-title-prefix-icon'));
    const suffixIconWidth = getElementMarginWidth(queryCellElement(cell, '>.vxe-cell-title-suffix-icon'));
    const sortIconWidth = getElementMarginWidth(queryCellElement(cell, '>.vxe-cell--sort'));
    const filterIconWidth = getElementMarginWidth(queryCellElement(cell, '>.vxe-cell--filter'));
    mWidth += dragIconWidth + checkboxIconWidth + requiredIconWidth + editIconWidth + prefixIconWidth + suffixIconWidth + filterIconWidth + sortIconWidth;
  }
  // 如果设置最小宽
  if (colMinWidth) {
    const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
    if (bodyScrollElem) {
      if ((0, _dom.isScale)(colMinWidth)) {
        const bodyWidth = bodyScrollElem.clientWidth - 1;
        const meanWidth = bodyWidth / 100;
        return Math.max(mWidth, Math.floor(_xeUtils.default.toInteger(colMinWidth) * meanWidth));
      } else if ((0, _dom.isPx)(colMinWidth)) {
        return Math.max(mWidth, _xeUtils.default.toInteger(colMinWidth));
      }
    }
  }
  return mWidth;
}
function isColumnInfo(column) {
  return column && (column.constructor === _columnInfo.ColumnInfo || column instanceof _columnInfo.ColumnInfo);
}
function createColumn($xeTable, options, renderOptions) {
  return isColumnInfo(options) ? options : (0, _vue.reactive)(new _columnInfo.ColumnInfo($xeTable, options, renderOptions));
}
function watchColumn($xeTable, props, column) {
  Object.keys(props).forEach(name => {
    (0, _vue.watch)(() => props[name], value => {
      column.update(name, value);
      if ($xeTable) {
        if (name === 'filters') {
          $xeTable.setFilter(column, value);
          $xeTable.handleUpdateDataQueue();
        } else if (['visible', 'fixed', 'width', 'minWidth', 'maxWidth'].includes(name)) {
          $xeTable.handleRefreshColumnQueue();
        }
      }
    });
  });
}
function assembleColumn($xeTable, elem, column, colgroup) {
  const {
    reactData
  } = $xeTable;
  const {
    staticColumns
  } = reactData;
  const parentElem = elem.parentNode;
  const parentColumn = colgroup ? colgroup.columnConfig : null;
  const parentCols = parentColumn ? parentColumn.children : staticColumns;
  if (parentElem && parentCols) {
    parentCols.splice(_xeUtils.default.arrayIndexOf(parentElem.children, elem), 0, column);
    reactData.staticColumns = staticColumns.slice(0);
  }
}
function destroyColumn($xeTable, column) {
  const {
    reactData
  } = $xeTable;
  const {
    staticColumns
  } = reactData;
  const matchObj = _xeUtils.default.findTree(staticColumns, item => item.id === column.id, {
    children: 'children'
  });
  if (matchObj) {
    matchObj.items.splice(matchObj.index, 1);
  }
  reactData.staticColumns = staticColumns.slice(0);
}
function getRootColumn($xeTable, column) {
  const {
    internalData
  } = $xeTable;
  const {
    fullColumnIdData
  } = internalData;
  if (!column) {
    return null;
  }
  let parentColId = column.parentId;
  while (fullColumnIdData[parentColId]) {
    const column = fullColumnIdData[parentColId].column;
    parentColId = column.parentId;
    if (!parentColId) {
      return column;
    }
  }
  return column;
}
const lineOffsetSizes = {
  mini: 3,
  small: 2,
  medium: 1
};
const countTreeExpand = (prevRow, params) => {
  let count = 1;
  if (!prevRow) {
    return count;
  }
  const {
    $table
  } = params;
  const {
    computeTreeOpts
  } = $table.getComputeMaps();
  const treeOpts = computeTreeOpts.value;
  const {
    transform,
    mapChildrenField
  } = treeOpts;
  const childrenField = treeOpts.children || treeOpts.childrenField;
  const rowChildren = prevRow[transform ? mapChildrenField : childrenField];
  if (rowChildren && $table.isTreeExpandByRow(prevRow)) {
    for (let index = 0; index < rowChildren.length; index++) {
      count += countTreeExpand(rowChildren[index], params);
    }
  }
  return count;
};
const getOffsetSize = $xeTable => {
  const {
    computeSize
  } = $xeTable.getComputeMaps();
  const vSize = computeSize.value;
  if (vSize) {
    return lineOffsetSizes[vSize] || 0;
  }
  return 0;
};
exports.getOffsetSize = getOffsetSize;
function calcTreeLine(params, prevRow) {
  const {
    $table,
    row
  } = params;
  const tableProps = $table.props;
  const tableReactData = $table.reactData;
  const tableInternalData = $table.internalData;
  const {
    showOverflow
  } = tableProps;
  const {
    scrollYLoad
  } = tableReactData;
  const {
    fullAllDataRowIdData
  } = tableInternalData;
  const {
    computeRowOpts,
    computeCellOpts,
    computeDefaultRowHeight
  } = $table.getComputeMaps();
  const rowOpts = computeRowOpts.value;
  const cellOpts = computeCellOpts.value;
  const defaultRowHeight = computeDefaultRowHeight.value;
  const rowid = getRowid($table, row);
  const rowRest = fullAllDataRowIdData[rowid];
  const currCellHeight = rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight;
  let expandSize = 1;
  if (prevRow) {
    expandSize = countTreeExpand(prevRow, params);
  }
  let cellHeight = currCellHeight;
  const vnHeight = rowRest.height;
  if (scrollYLoad) {
    if (!showOverflow) {
      cellHeight = vnHeight || currCellHeight;
    }
  }
  return cellHeight * expandSize - (prevRow ? 1 : 12 - getOffsetSize($table));
}
function mergeBodyMethod(mergeList, _rowIndex, _columnIndex) {
  for (let mIndex = 0; mIndex < mergeList.length; mIndex++) {
    const {
      row: mergeRowIndex,
      col: mergeColIndex,
      rowspan: mergeRowspan,
      colspan: mergeColspan
    } = mergeList[mIndex];
    if (mergeColIndex > -1 && mergeRowIndex > -1 && mergeRowspan && mergeColspan) {
      if (mergeRowIndex === _rowIndex && mergeColIndex === _columnIndex) {
        return {
          rowspan: mergeRowspan,
          colspan: mergeColspan
        };
      }
      if (_rowIndex >= mergeRowIndex && _rowIndex < mergeRowIndex + mergeRowspan && _columnIndex >= mergeColIndex && _columnIndex < mergeColIndex + mergeColspan) {
        return {
          rowspan: 0,
          colspan: 0
        };
      }
    }
  }
}
function clearTableDefaultStatus($xeTable) {
  const {
    props,
    internalData
  } = $xeTable;
  internalData.initStatus = false;
  $xeTable.clearSort();
  $xeTable.clearCurrentRow();
  $xeTable.clearCurrentColumn();
  $xeTable.clearRadioRow();
  $xeTable.clearRadioReserve();
  $xeTable.clearCheckboxRow();
  $xeTable.clearCheckboxReserve();
  $xeTable.clearRowExpand();
  $xeTable.clearTreeExpand();
  $xeTable.clearTreeExpandReserve();
  $xeTable.clearPendingRow();
  if ($xeTable.clearFilter) {
    $xeTable.clearFilter();
  }
  if ($xeTable.clearSelected && (props.keyboardConfig || props.mouseConfig)) {
    $xeTable.clearSelected();
  }
  if ($xeTable.clearCellAreas && props.mouseConfig) {
    $xeTable.clearCellAreas();
    $xeTable.clearCopyCellArea();
  }
  return $xeTable.clearScroll();
}
function clearTableAllStatus($xeTable) {
  if ($xeTable.clearFilter) {
    $xeTable.clearFilter();
  }
  return clearTableDefaultStatus($xeTable);
}
function rowToVisible($xeTable, row) {
  const tableProps = $xeTable.props;
  const reactData = $xeTable.reactData;
  const internalData = $xeTable.internalData;
  const {
    computeLeftFixedWidth,
    computeRightFixedWidth,
    computeRowOpts,
    computeCellOpts,
    computeDefaultRowHeight
  } = $xeTable.getComputeMaps();
  const {
    showOverflow
  } = tableProps;
  const {
    scrollYLoad
  } = reactData;
  const {
    elemStore,
    afterFullData,
    fullAllDataRowIdData,
    isResizeCellHeight
  } = internalData;
  const rowOpts = computeRowOpts.value;
  const cellOpts = computeCellOpts.value;
  const defaultRowHeight = computeDefaultRowHeight.value;
  const leftFixedWidth = computeLeftFixedWidth.value;
  const rightFixedWidth = computeRightFixedWidth.value;
  const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
  const rowid = getRowid($xeTable, row);
  if (bodyScrollElem) {
    const bodyHeight = bodyScrollElem.clientHeight;
    const bodyScrollTop = bodyScrollElem.scrollTop;
    const trElem = bodyScrollElem.querySelector(`[rowid="${rowid}"]`);
    if (trElem) {
      const trOffsetParent = trElem.offsetParent;
      const trOffsetTop = trElem.offsetTop + (trOffsetParent ? trOffsetParent.offsetTop : 0);
      const trHeight = trElem.clientHeight;
      // 检测行是否在可视区中
      if (trOffsetTop < bodyScrollTop || trOffsetTop > bodyScrollTop + bodyHeight) {
        return $xeTable.scrollTo(null, trOffsetTop);
      } else if (trOffsetTop + trHeight >= bodyHeight + bodyScrollTop) {
        return $xeTable.scrollTo(null, bodyScrollTop + trHeight);
      }
    } else {
      // 如果是虚拟渲染滚动
      if (scrollYLoad) {
        const isCustomCellHeight = isResizeCellHeight || cellOpts.height || rowOpts.height;
        if (!isCustomCellHeight && showOverflow) {
          return $xeTable.scrollTo(null, ($xeTable.findRowIndexOf(afterFullData, row) - 1) * defaultRowHeight);
        }
        let scrollTop = 0;
        const rowRest = fullAllDataRowIdData[rowid] || {};
        const rHeight = rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight;
        for (let i = 0; i < afterFullData.length; i++) {
          const currRow = afterFullData[i];
          const currRowid = getRowid($xeTable, currRow);
          if (currRow === row || currRowid === rowid) {
            break;
          }
          const currRowRest = fullAllDataRowIdData[currRowid] || {};
          scrollTop += currRowRest.resizeHeight || cellOpts.height || rowOpts.height || currRowRest.height || defaultRowHeight;
        }
        if (scrollTop < bodyScrollTop) {
          return $xeTable.scrollTo(null, scrollTop - leftFixedWidth - 1);
        }
        return $xeTable.scrollTo(null, scrollTop + rHeight - (bodyHeight - rightFixedWidth - 1));
      }
    }
  }
  return Promise.resolve();
}
function colToVisible($xeTable, column, row) {
  const reactData = $xeTable.reactData;
  const internalData = $xeTable.internalData;
  const {
    computeLeftFixedWidth,
    computeRightFixedWidth
  } = $xeTable.getComputeMaps();
  const {
    scrollXLoad
  } = reactData;
  const {
    elemStore,
    visibleColumn
  } = internalData;
  const leftFixedWidth = computeLeftFixedWidth.value;
  const rightFixedWidth = computeRightFixedWidth.value;
  const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
  if (column.fixed) {
    return Promise.resolve();
  }
  if (bodyScrollElem) {
    const bodyWidth = bodyScrollElem.clientWidth;
    const bodyScrollLeft = bodyScrollElem.scrollLeft;
    let tdElem = null;
    if (row) {
      const rowid = getRowid($xeTable, row);
      tdElem = bodyScrollElem.querySelector(`[rowid="${rowid}"] .${column.id}`);
    }
    if (!tdElem) {
      tdElem = bodyScrollElem.querySelector(`.${column.id}`);
    }
    if (tdElem) {
      const tdOffsetParent = tdElem.offsetParent;
      const tdOffsetLeft = tdElem.offsetLeft + (tdOffsetParent ? tdOffsetParent.offsetLeft : 0);
      const cellWidth = tdElem.clientWidth;
      // 检测是否在可视区中
      if (tdOffsetLeft < bodyScrollLeft + leftFixedWidth) {
        return $xeTable.scrollTo(tdOffsetLeft - leftFixedWidth - 1);
      } else if (tdOffsetLeft + cellWidth - bodyScrollLeft > bodyWidth - rightFixedWidth) {
        return $xeTable.scrollTo(tdOffsetLeft + cellWidth - (bodyWidth - rightFixedWidth - 1));
      }
    } else {
      // 检测是否在虚拟渲染可视区中
      if (scrollXLoad) {
        let scrollLeft = 0;
        const cellWidth = column.renderWidth;
        for (let i = 0; i < visibleColumn.length; i++) {
          const currCol = visibleColumn[i];
          if (currCol === column || currCol.id === column.id) {
            break;
          }
          scrollLeft += currCol.renderWidth;
        }
        if (scrollLeft < bodyScrollLeft) {
          return $xeTable.scrollTo(scrollLeft - leftFixedWidth - 1);
        }
        return $xeTable.scrollTo(scrollLeft + cellWidth - (bodyWidth - rightFixedWidth - 1));
      }
    }
  }
  return Promise.resolve();
}